﻿using HNRoadFormatConverter.Commons;
using HNRoadFormatConverter.Entitys;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HNRoadFormatConverter.MyEntitys
{
    public class ProjectInfo
    {
        private static LogHelper _log = new LogHelper(typeof(ProjectInfo));
        /// <summary>
        /// 项目数据
        /// </summary>
        public ProjectInfo(string projectPath)
        {
           this._PrjPath = projectPath;
            this.prj = projectPath;
            SetProjectInfo(projectPath);
        }
      
        
        /// <summary>
        /// 道路方向 A:上行 B：下行
        /// </summary>
        public string _Direction { get; set; }
        public int _DirectionInt { get; set; }
        /// <summary>
        /// 路线编号
        /// 行政等级代码(1位)+三位编号+县级行政区划代码（6位）+方向
        /// </summary>
        /// 
        /// <summary>
        /// 工程路径
        /// </summary>
        private string _PrjPath;

        public DirectoryInfo _DataDir;
        public string RoadNum { get; set; }

        public string _Province;//省
        public string _City;//市
        public string _District;//县
        private string prj;
        public string _RoadCode;//路线代码
        public string _RoadName;//路线名
        public int _StartMile;//起点桩号
        public string _RoadGrade;//公路等级
        public string _RoadNum;//车道
        public int _EndMile;//终点桩号
        public int _EndDmi;//总里程

        public string _DataDate;
        public string _DataTime;
        public string _DataPerson;
        public string _DataWeather;
        bool IsComplete = false;
        /// <summary>
        /// 设置工程信息 
        /// 路线编号 上下行，道路起始及终点
        /// </summary>
        /// <param name="proPath"></param>
        private void SetProjectInfo(string proPath)
        {

            string proInfoTxtPath = Path.Combine(proPath, "ProjectInfo.txt");
            if (File.Exists(proInfoTxtPath))
            {
                
                SetPara(File.ReadAllLines(proInfoTxtPath));
                //获取转换中间文件夹
                GetConvertPath();
                //获取破损图片路径
                GetRoadPicPath();
                //获得景观图片路径
                GetStreetPicPath();
                //获得时间
                GetTime();
                //
            }
            else
            {
                MessageBox.Show("缺少工程文件ProjectInfo.txt，请检查数据完整性"); 
                Application.Exit();
            }
        }
        /// <summary>
        /// 图片及桩号结构体列表
        /// </summary>
        public List<PicAndMile> GetPicAndMiles(bool road , CityModelItem stanard)
        {
            List<PicAndMile> picAndMiles = new List<PicAndMile>();
            string GetResultPicName(PicAndMile picAndMile)
            {
                if (stanard == CityModelItem.甘肃省单位一定制)
                {
                    var direction = ConvertProName.Last();
                    string RoadName = ConvertProName.Substring(0, ConvertProName.Length - 1);
                    return $"{RoadName}-{(picAndMile.Mile * 0.001).ToString("f3")}-{DateDay}";
                }
                else
                {
                    return DateDay + "_" + ConvertProName + "_" + (picAndMile.Mile * 0.001).ToString("f3");
                }
            }
            if (road)
            {

                
                string pciBasePath = prj + "\\RoadImg\\Camera0";
                string indexTxt = pciBasePath + "\\Road2Mile.txt";
                if (!File.Exists(indexTxt))
                {
                    MessageBox.Show(prj+"路面图像索引文件不存在请检查！");
                    System.Environment.Exit(0);
                }
                string[] strs =  File.ReadAllLines (indexTxt);
                foreach (var str in strs)
                {      
                    PicAndMile _picAndMile = new PicAndMile();
                    var sp = str.Split(' ');
                    _picAndMile.Mile = int.Parse(sp[0]);
                    _picAndMile.PicPath =pciBasePath+ sp[1];
                    _picAndMile.sourceTxt = str;

                    _picAndMile.ResultPicName = GetResultPicName(_picAndMile);
                    picAndMiles.Add(_picAndMile);
                }
               
            }
            else
            { //路面图像
                string pciBasePath = prj + "\\StreetImg\\Camera0";
                string indexTxt = pciBasePath + "\\Street2Mile.txt";
                if (!File.Exists(indexTxt))
                {
                    MessageBox.Show(prj + "景观图像索引文件不存在请检查！");
                    System.Environment.Exit(0);
                }
                string[] strs = File.ReadAllLines(indexTxt);
                foreach (var str in strs)
                {
                    PicAndMile _picAndMile = new PicAndMile();
                    var sp = str.Split(' ');
                    _picAndMile.Mile = int.Parse(sp[0]);
                    _picAndMile.PicPath = pciBasePath + sp[1];
                    _picAndMile.sourceTxt = str;
                    _picAndMile.ResultPicName = GetResultPicName(_picAndMile);
                    picAndMiles.Add(_picAndMile);
                }


            }
            return picAndMiles;

        }


        public List<PicAndMile> GetPicAndMilesHuNan(bool road)
        {
            List<PicAndMile> picAndMiles = new List<PicAndMile>();
            if (road)
            {


                string pciBasePath = prj + "\\RoadImg\\Camera0";
                string indexTxt = pciBasePath + "\\Road2Mile.txt";
                if (!File.Exists(indexTxt))
                {
                    MessageBox.Show(prj + "路面图像索引文件不存在请检查！");
                    System.Environment.Exit(0);
                }
                string[] strs = File.ReadAllLines(indexTxt);
                foreach (var str in strs)
                {
                    PicAndMile _picAndMile = new PicAndMile();
                    var sp = str.Split(' ');
                    _picAndMile.Mile = int.Parse(sp[0]);
                    _picAndMile.PicPath = pciBasePath + sp[1];
                    _picAndMile.sourceTxt = str;


                    string mile =Form1.ConvertIntToFormattedString(_picAndMile.Mile);
                    _picAndMile.ResultPicName = ConvertProName + "-" + mile + "-" + mile; 
                    picAndMiles.Add(_picAndMile);
                }

            }
            else
            { //路面图像
                string pciBasePath = prj + "\\StreetImg\\Camera0";
                string indexTxt = pciBasePath + "\\Street2Mile.txt";
                if (!File.Exists(indexTxt))
                {
                    MessageBox.Show(prj + "景观图像索引文件不存在请检查！");
                    System.Environment.Exit(0);
                }
                string[] strs = File.ReadAllLines(indexTxt);
                foreach (var str in strs)
                {
                    PicAndMile _picAndMile = new PicAndMile();
                    var sp = str.Split(' ');
                    _picAndMile.Mile = int.Parse(sp[0]);
                    _picAndMile.PicPath = pciBasePath + sp[1];
                    _picAndMile.sourceTxt = str;
                    string mile = Form1.ConvertIntToFormattedString(_picAndMile.Mile);
                    _picAndMile.ResultPicName = ConvertProName + "-" + mile + "-" + mile;
                   // _picAndMile.ResultPicName = DateDay + "_" + ConvertProName + "_" + (_picAndMile.Mile * 0.001).ToString("f3");
                    picAndMiles.Add(_picAndMile);
                }


            }
            return picAndMiles;

        }
        /// <summary>
        /// 转换中间文件夹
        /// </summary>
        public DirectoryInfo ConvertPath { get; set; }
        /// <summary>
        /// 转换工程名称
        /// </summary>
        public string ConvertProName { get; set; }
        /// <summary>
        /// 转换完成标志
        /// </summary>


        public bool ConvertOk
        {
            get;
            set;
        }
        public string ConvertSourcePath { get; set; }
        private void GetConvertPath()
        {
           string [] paths =  Directory.GetDirectories(this._PrjPath, "ConverSource");
            if (paths.Length==0)
            {
                MessageBox.Show($"{this._PrjPath}不具有转换中间数据文件夹ConverSource请检查");
                Application.Exit();
            }
            string path = paths[0];
            DirectoryInfo temp = new DirectoryInfo(path);
            path = temp.GetDirectories().First().FullName;
            ConvertSourcePath = path;
            ConvertProName = Path.GetFileNameWithoutExtension(path);
            DirectoryInfo directory = new DirectoryInfo(path);
            ConvertPath = directory;
        }
        public string DateDay { get; set; }
        public string DateMin { get;set; }
        public string RoadPicPath { get; set; }
         public   string StreetPicPath { get; set; }
        private void GetRoadPicPath()
        {
             if (Directory.Exists(prj + "\\RoadImg\\Camera0"))
            {
                RoadPicPath = prj + "\\RoadImg\\Camera0";
            }

         }
        private void GetStreetPicPath()
        {
            if (Directory.Exists(prj + "\\StreetImg\\Camera0"))
            {
                StreetPicPath = prj + "\\StreetImg\\Camera0";
            }

        }
        /// <summary>
        /// 获得时间
        /// </summary>
        private void GetTime()
        {
          /*  DirectoryInfo dr = new DirectoryInfo(ConvertSourcePath);
           DirectoryInfo info =  dr.GetDirectories("景观图像", SearchOption.AllDirectories).First();
            var timePath = info.GetDirectories().First();
            DateDay = timePath.Name;
            DateMin = timePath.GetDirectories().First().Name.Split('_').LastOrDefault();
          */



        }
        public void SetConvertSign(bool isok)
        {
            this.ConvertOk = isok;
            string proInfoTxtPath = Path.Combine(this._PrjPath, "ProjectInfo.txt");
            if (!File.Exists(proInfoTxtPath))
                return;

            if (isok)
            {
               //string temp  = File.ReadAllText(proInfoTxtPath);
               // if (!temp.Contains("ConvertOk：True"))
               // {
               //     //File.AppendAllLines(proInfoTxtPath, new string[] { "ConvertOk：True" });
               //     //_log.Error($"{this.ConvertProName} 转换成功");
               // }
            }
            else
            {
                //string temp = File.ReadAllText(proInfoTxtPath);
                //if (!temp.Contains("ConvertOk：False"))
                //{
                //    File.AppendAllLines(proInfoTxtPath, new string[] { "ConvertOk：False" });
                //    _log.Error($"{this.ConvertProName} 转换失败");
                //}
             
            }

        }

        private void SetPara(string[] strings)
        {
            foreach (string LineStr in strings)
            {
                var s = LineStr.Split('：');
                switch (s[0])
                {

                    case "省": _Province = s[1]; break;
                    //case "ConvertOk":
                    //    {
                    //        if (s[1] == "True")
                    //        {
                    //            this.ConvertOk = true;
                    //        }
                    //        else
                    //        {
                    //            this.ConvertOk = false;
                    //        }
                    //        break;
                    //    }
                    case "市": _City = s[1]; break;
                    case "县": _District = s[1]; break;
                    case "工程起点道路编号": _RoadCode = s[1]; break;
                    case "工程起点道路名称": _RoadName = s[1]; break;
                    case "工程起点桩号":
                        _StartMile = Convert.ToInt32(s[1].Split('+')[0].Replace("K", "")) * 1000 +
                     Convert.ToInt32(s[1].Split('+')[1]); break;
                    case "行车方向":
                        {
                            if (s[1] == "上行")
                            {
                                _DirectionInt = 1; _Direction = "A";
                            }
                            
                            else if (s[1] == "下行")
                            {
                                _Direction = "B";
                                _DirectionInt = -1;
                            }
                           
                        }
                        break;
                    case "公路等级": _RoadGrade = s[1]; break;

                    case "工程终点道路标识桩号":
                        _EndMile = Convert.ToInt32(s[1].Split('+')[0].Replace("K", "")) * 1000 +
    Convert.ToInt32(s[1].Split('+')[1]); break;

                    case "工程总里程数":
                        {
                            IsComplete = true;
                            _EndDmi = Convert.ToInt32(s[1].Split('+')[0].Replace("K", "")) * 1000 +
                            Convert.ToInt32(s[1].Split('+')[1]); break;

                        }
                    case "工程开始时刻": _DataTime = s[1]; DateMin = s[1]; break;
                    case "车道": _RoadNum = s[1]; break;
                    case "采集日期": _DataDate = s[1]; DateDay = s[1]; break;
                }
            }
            if (!IsComplete)
            {
                if (Directory.Exists(prj + "\\RoadImg\\Camera0"))
                {
                    int imgnum = 0;
                    string[] dirs = Directory.GetDirectories(prj + "\\RoadImg\\Camera0");
                    Array.Sort(dirs);
                    foreach (string dir in dirs)
                    {
                        imgnum += Directory.GetFiles(dir, "*.jpg").Length;
                    }
                    _EndDmi = imgnum * _RoadImgDis;
                }
                else if (File.Exists(prj + "\\IRIMTD\\DAQ0\\Resample.txt"))
                {
                    string[] ttstr = File.ReadAllLines(prj + "\\IRIMTD\\DAQ0\\Resample.txt");
                    _EndDmi = (int)Math.Floor(ttstr.Length * 0.05);
                }
                else if (File.Exists(prj + "\\camera0\\rut.txt"))
                {
                    string[] ttstr = File.ReadAllLines(prj + "\\camera0\\rut.txt");
                    _EndDmi = (int)Math.Floor(ttstr.Length * _RutDis * 0.01);
                }
                else if (Directory.Exists(prj + "\\RoadImg\\Camera0"))
                {
                    int imgnum = 0;
                    string[] dirs = Directory.GetDirectories(prj + "\\StreetImg\\Camera0");
                    Array.Sort(dirs);
                    foreach (string dir in dirs)
                    {
                        imgnum += Directory.GetFiles(dir, "*.jpg").Length;
                    }
                    _EndDmi = imgnum * _StreetImgDis;
                }
                _EndMile = _StartMile + _DirectionInt * _EndDmi;
                string[] appstrs = new string[3];
                appstrs[0] = "工程终点道路标识桩号：" + _EndMile.ToString("K0000+000");
                appstrs[1] = "工程总里程数：" + _EndDmi.ToString("K0000+000");
                File.AppendAllLines(prj + @"\ProjectInfo.txt", appstrs, Encoding.UTF8);
            }
            TranDmi2Mile();
            string tmppath = _PrjPath + @"\ProjectInfo.txt";
            tmppath = _PrjPath + @"\Setting.ini";
            if (File.Exists(tmppath))
            {
                IniFiles iniset = new IniFiles(tmppath);
                _IsStreet = iniset.ReadBool("工作模式", "Street", false);
                _IsRoad = iniset.ReadBool("工作模式", "Road", false);
                _IsIRIMTD = iniset.ReadBool("工作模式", "IRIMTD", false);
                _IsDIRIMTD = iniset.ReadBool("工作模式", "DIRIMTD", false);
                _IsMMTD = iniset.ReadBool("工作模式", "MMTD", false);

                _GeoAlig = iniset.ReadInteger("工作模式", "GeoAlig", 0);
                _IsRut = iniset.ReadBool("工作模式", "Rut", false);
                bool IsSRut = iniset.ReadBool("工作模式", "SRut", false);
                bool IsDRut = iniset.ReadBool("工作模式", "DRut", false);
                bool Is3DRut = iniset.ReadBool("工作模式", "3DRut", false);
                if (IsSRut)
                    _RutMode = 0;
                if (IsDRut)
                    _RutMode = 1;
                if (Is3DRut)
                    _RutMode = 2;

                _IsDStreet = iniset.ReadBool("工作模式", "DStreet", false);
                _DMIScale = Convert.ToDouble(iniset.ReadString("工作模式", "DMIScale", "1000")) * 0.001;
                _RoadImgDis = iniset.ReadInteger("Parm", "RoadDis", 2);
                _StreetImgDis = iniset.ReadInteger("Parm", "StreetDis", 20);
                _PanoImgDis = iniset.ReadInteger("Parm", "PanoDis", 20);
                _RutDis = iniset.ReadInteger("Parm", "RUT_Dis", 50);
                _IsPano = iniset.ReadBool("工作模式", "Pano", false);

            }
            else
            {
                MessageBox.Show(_PrjPath + "缺少工程配置文件Setting.ini，请检查数据是否完整！");
                Application.Exit();
            }
        }




        /// <summary>
        /// 将编码器的 里程值 转换成路边 桩号
        /// </summary>
        /// <param name="prj"></param>
        private void TranDmi2Mile()
        {
            List<DmiMile> ListDM = new List<DmiMile>();
            string fname = _PrjPath + @"\MileStoneCaliInfo.txt";
            ListDM.Add(new DmiMile(0, _StartMile));
            if (File.Exists(fname))
            {
                string[] sinfo = File.ReadAllLines(fname);
                foreach (string s in sinfo)
                {
                    string[] str = s.Split(' ');
                    if (str.Length > 1)
                    {
                        ListDM.Add(new DmiMile(int.Parse(str[0]), int.Parse(str[1])));
                    }
                }
            }
            else
            {
                int temp = _StartMile + _EndDmi * _DirectionInt;
                if (temp < 0 && _EndMile > 0)
                {
                    _EndMile = 0;
                    _EndDmi = _StartMile;
                    string[] sinfo = File.ReadAllLines(_PrjPath + @"\ProjectInfo.txt");
                    for (int i = 0; i < sinfo.Length; ++i)
                    {
                        //if (sinfo[i].Contains("工程终点道路实际桩号："))
                        //{
                        //    sinfo[i] = "工程终点道路实际桩号：" + _EndMile.ToString("K0000+000");
                        //}
                        //else 
                        if (sinfo[i].Contains("工程终点道路标识桩号："))
                        {
                            sinfo[i] = "工程终点道路标识桩号：" + _EndMile.ToString("K0000+000");
                        }
                        else if (sinfo[i].Contains("工程总里程数："))
                        {
                            sinfo[i] = "工程总里程数：" + _EndDmi.ToString("K0000+000");
                        }
                    }
                    File.WriteAllLines(_PrjPath + @"\ProjectInfo.txt", sinfo, Encoding.UTF8);
                }
            }

            ListDM.Add(new DmiMile(_EndDmi, _EndMile));
            int dmlen = ListDM.Count;
            for (int i = 0; i < dmlen - 1; ++i)
            {
                if (ListDM[i]._Mile == ListDM[i + 1]._Mile)
                {
                    ListDM.RemoveAt(i);
                    dmlen--;
                    i--;
                }
            }

            if (_DirectionInt > 0)//升序
            {
                ListDM.Sort(delegate (DmiMile x, DmiMile y) { return x._Mile.CompareTo(y._Mile); });
            }
            else if (_DirectionInt < 0)//降序
            {
                ListDM.Sort(delegate (DmiMile x, DmiMile y) { return y._Mile.CompareTo(x._Mile); });
            }

            _DmiMileLen = ListDM.Count;
            _DmiMile = new double[_DmiMileLen, 2];//里程，桩号
            _D2MScale = new double[_DmiMileLen];
            _D2MScale[0] = _DirectionInt;
            FileStream fw = new FileStream(_PrjPath + @"\Dmi2Mile.txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(fw);
            for (int i = 0; i < _DmiMileLen; ++i)
            {
                _DmiMile[i, 0] = ListDM[i]._Dmi;
                _DmiMile[i, 1] = ListDM[i]._Mile;
                if (i > 0) _D2MScale[i] = (_DmiMile[i, 0] - _DmiMile[i - 1, 0]) / (_DmiMile[i, 1] - _DmiMile[i - 1, 1]);
                sw.WriteLine(string.Format("{0} {1}", ListDM[i]._Dmi, ListDM[i]._Mile), Encoding.UTF8);
            }
            sw.Close();
            fw.Close();

            string tfname = _PrjPath + "\\RoadStatuMarkInfo.txt";
            if (File.Exists(tfname))
            {
                List<string> strlist = new List<string>();
                string[] strs = File.ReadAllLines(tfname, Encoding.UTF8);
                for (int i = 0; i < strs.Length; ++i)
                {
                    strs[i] = strs[i].Replace("K", "");
                    strs[i] = strs[i].Replace("k", "");
                    strs[i] = strs[i].Replace("+", "");
                    string[] sstrs = strs[i].Split(' ');
                    if (sstrs.Length < 2)
                        continue;
                    int tdmi = (int)Convert.ToDouble(sstrs[2]);
                    //int tmile = (int)Convert.ToDouble(sstrs[0]);
                    int tmile = (int)Dmi2Mile(tdmi);
                    for (int j = 0; j < ListDM.Count - 1; ++j)
                    {
                        if (ListDM[j]._Dmi <= tdmi && ListDM[j + 1]._Dmi > tdmi)
                        {
                            strs[i] = string.Format("{0} {0} {1} {2}", tmile, tdmi, sstrs[sstrs.Length - 1]);
                            break;
                        }
                    }
                    strlist.Add(strs[i]);
                }
                File.WriteAllLines(tfname, strlist, Encoding.UTF8);
            }
        }

        /// <summary>
        /// 里程转换为桩号
        /// </summary>
        /// <param name="indmi">里程</param>
        /// <returns>桩号</returns>
        public int Dmi2Mile(float indmi)
        {
            for (int j = 1; j < _DmiMileLen; ++j)
            {
                if ((indmi >= _DmiMile[j - 1, 0] && indmi <= _DmiMile[j, 0]) || j == _DmiMileLen - 1)
                {
                    //return Math.Abs((int)Math.Round((indmi - _DmiMile[j - 1, 0]) / _D2MScale[j] + _DmiMile[j - 1, 1]));                    
                    return (int)Math.Round((indmi - _DmiMile[j - 1, 0]) / _D2MScale[j] + _DmiMile[j - 1, 1]);
                }
            }
            return 0;
        }

        private int _DmiMileLen;//里程桩号关联数组个数
        private double[,] _DmiMile;//里程桩号关联数组
        private double[] _D2MScale;//里程/桩号的系数

        public bool _IsIRIMTD = false;//是否采集了平整度构造深度
        public bool _IsDIRIMTD = false;//是否是双平整度构造深度，true-双，false-单

        /// <summary>
        /// 是否采集了中间构造深度，true-是，false-否
        /// </summary>
        public bool _IsMMTD = false;

        /// <summary>
        /// 是否采集了车辙，true-是，false-否
        /// </summary>
        public bool _IsRut = false;
        /// <summary>
        /// 车辙模块模式，0-2D单车辙模块，1-2D双车辙模块，2-3D车辙模块
        /// </summary>
        public int _RutMode = 0;
        /// <summary>
        /// 几何线形工作模式，0-不采集几何线形数据，1-采集几何线形数据
        /// </summary>
        public int _GeoAlig = 0;

        public bool _IsDStreet = false;//是否是双景观，true-双，false-单
        public bool _IsRoad = false;//是否采集了路面
        public bool _IsStreet = false;//是否采集了景观
        public bool _IsPano = false;//是否采集了全景

        public int _RutDis = 50;//车辙出值间距
        public int _RoadImgDis = 2;//路面图像采集间距
        public int _StreetImgDis = 20;//景观图像采集间距
        public int _PanoImgDis = 20;//景观图像采集间距
        public double _DMIScale = 1.0; //编码器相关系数
    }
}
